package com.uplift.mgt.customer.service.impl;

import java.util.*;

import javax.mail.internet.MimeMessage;

import com.uplift.common.Const;
import com.uplift.common.base.BusinessException;
import com.uplift.common.base.ServiceReslut;
import com.uplift.common.utils.JExcelReadUtils;
import com.uplift.mgt.sys.model.DictModel;
import com.uplift.mgt.sys.service.IDictService;
import com.uplift.mgt.user.model.User;
import com.uplift.sec.SecurityContext;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.uplift.mgt.customer.dao.CustomerMapper;
import com.uplift.mgt.customer.model.Customer;
import com.uplift.mgt.customer.service.ICustomerService;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

@Service
@Transactional
public class CustomerServiceImpl implements ICustomerService {

	@Autowired
	private CustomerMapper customerMapper;

	@Autowired
	private JavaMailSender mailSender;
	
	@Autowired
	private TaskExecutor taskExecutor;

	@Autowired
	private IDictService dictService;

	private List<Map<String, Object>> sourceCodeMap;

	/** excle 每列的字段名称 */
	private String[] excel_cloum_names = new String[] {"登录名","密码","客户名称","客户编号","客户来源","生日","邮箱","性别"};
	
	@Override
	public List<Map<String, Object>> queryCustomer(Customer customer) {
		PageHelper.startPage(customer.getPage(), customer.getLimit());
		return this.customerMapper.selectCustomer(customer);
	}

	@Override
	public List<Map<String, Object>> queryAllCustomer(Customer customer) {
		return this.customerMapper.selectCustomer(customer);
	}

	@Override
	public ServiceReslut addCustomer(Customer customer) {
		//Map<String, Object> data = new HashMap<>();

		Customer queryCustomer = new Customer();
		queryCustomer.setUsername(customer.getUsername());
		List<Map<String, Object>> maps = this.customerMapper.selectCustomerEqual(queryCustomer);
		if(maps!=null && maps.size()>0) {
			return ServiceReslut.newServiceReslut(0, "用户名已存在");
		}
		queryCustomer = new Customer();
		queryCustomer.setUserCode(customer.getUserCode());
		maps = this.customerMapper.selectCustomerEqual(queryCustomer);
		if(maps!=null && maps.size()>0) {
			return ServiceReslut.newServiceReslut(0, "用户编号已存在");
		}

		Map<String, Object> sessionUser = SecurityContext.getSessionUser();
		if(sessionUser == null) {
			return ServiceReslut.newServiceReslut(0, "获取登录用户信息失败");
		}

		customer.setCreateUserId((String) sessionUser.get("id"));
		customer.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		customer.setState("1");
		customer.setCreateTime(new Date());
		return ServiceReslut.newServiceReslut(customerMapper.insertCustomer(customer), "");
	}

	@Override
	public ServiceReslut updateCustomer(Customer customer) {
		if(StringUtils.isBlank(customer.getId())) {
			return ServiceReslut.newServiceReslut(0, "id为空");
		}
		customer.setUpdateTime(new Date());
		int rows = this.customerMapper.updateCustomer(customer);
		// 修改客户密码则发送邮件通知客户
		if (rows > 0 && StringUtils.isNotBlank(customer.getPassword())) {
			Customer pCustomer = new Customer();
			pCustomer.setId(customer.getId());
			List<Map<String, Object>> pCustomerList = this.customerMapper.selectCustomer(pCustomer);
			Map<String, Object> pCustomerMap = null;
			if (pCustomerList != null && pCustomerList.size() > 0) {
				pCustomerMap = pCustomerList.get(0);
			}
			// 查询客户邮箱并发送邮件
			if (pCustomerMap != null) {
				String recipientAddress = MapUtils.getString(pCustomerMap, "email");
				String subject = "Uplife系统密码找回";
				String text = "<html><META http-equiv=Content-Type content='text/html; charset=UTF-8'><body>" + 
						"亲爱的Uplife用户：<br/>" + 
						"您的密码已修改<br/>" + 
						"&nbsp;&nbsp;密码：" + customer.getPassword() + "<br/>" + 
						"若您有任何疑问，请联系客服人员。<br/>";
					text += "</body></html>";
				try {
					MimeMessage message = this.mailSender.createMimeMessage();
					MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
					helper.setFrom(Const.MAIL_SENDER);
					helper.setTo(recipientAddress);
					helper.setSubject(subject);
					helper.setText(text, true);
					
					this.taskExecutor.execute(new Runnable() {
						
						@Override
						public void run() {
							mailSender.send(message);
						}
						
					});
					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		}
		
		return ServiceReslut.newServiceReslut(rows, "");
	}

	@Override
	public ServiceReslut deleteCustomer(Customer customer) {
		if(StringUtils.isBlank(customer.getId())) {
			return ServiceReslut.newServiceReslut(0, "id为空");
		}

		String[] ids = StringUtils.split(customer.getId(), ",");

		Customer _customer = null;
		for (String id : ids) {
			_customer = new Customer();
			_customer.setId(id);
			_customer.setState("0");		//删除状态
			_customer.setUpdateTime(new Date());

			customerMapper.updateCustomer(_customer);
		}

		return ServiceReslut.newServiceReslut(1, "");
	}

	@Override
	public void importUser(MultipartHttpServletRequest request) {
		try {
			MultipartFile file = request.getFile("file");
			if(file == null) {
				throw new BusinessException("导入失败，导入文件为空", 400, null);
			}
			List<Map<String, String>> datas = JExcelReadUtils.readExcelSheet1(file.getInputStream(), -1, 2, -1);
			if(CollectionUtils.isEmpty(datas)) {
				throw new BusinessException("导入失败，内容为空", 400, null);
			}

			if(!JExcelReadUtils.checkImprtExcelFormat(datas.get(0), excel_cloum_names)) {
				throw new BusinessException("导入失败，excle 模版错误", 400, null);
			}

			List<Customer> userList = createUserList(datas);
			if(CollectionUtils.isEmpty(userList)) {
				throw new BusinessException("导入失败，内容为空", 400, null);
			}

			for (Customer customer : userList) {
				this.customerMapper.insertCustomer(customer);
			}
		} catch (Exception e) {
			if (e instanceof BusinessException) {
				throw new BusinessException(e);
			} else {
				throw new BusinessException("导入失败", 400, null);
			}
		}
	}

	@Override
	public Map<String, Object> queryCustomerByCode(String userCode) {

		Customer customer = new Customer();
		customer.setUserCode(userCode);

		List<Map<String, Object>> maps = this.customerMapper.selectCustomerEqual(customer);
		if(CollectionUtils.isEmpty(maps)) {
			return null;
		}

		return maps.get(0);
	}

	@Override
	public Map<String, Object> queryCustomerByName(String userName) {

		Customer customer = new Customer();
		customer.setUsername(userName);

		List<Map<String, Object>> maps = this.customerMapper.selectCustomerEqual(customer);
		if(CollectionUtils.isEmpty(maps)) {
			return null;
		}

		return maps.get(0);
	}

	/**
	 * 创建客户list
	 * @param datas
	 * @return
	 */
	public List<Customer> createUserList(List<Map<String, String>> datas) {
		List<Customer> users = new ArrayList<>();

		for (int i = 1; i < datas.size(); i++) {
			users.add(createUserData(datas.get(i), i));
		}

		return users;
	}

	/**
	 * 生成客户对象
	 * @param data
	 * @return
	 */
	public Customer createUserData(Map<String, String> data, int row) {
		if(isUserExist(data.get("0"))) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]已存在", row, data.get("0")), 400, null);
		}
		Customer customer = new Customer();
		customer.setUsername(data.get("0"));
		if(StringUtils.isBlank(data.get("1"))) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]密码为空", row,data.get("0")), 400, null);
		}
		customer.setPassword(data.get("1"));

		if(StringUtils.isBlank(data.get("2"))) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]客户名为空", row,data.get("0")), 400, null);
		}
		customer.setName(data.get("2"));

		if(StringUtils.isBlank(data.get("3"))) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]客户编号为空", row,data.get("0")), 400, null);
		}
		customer.setUserCode(data.get("3"));

		if(StringUtils.isBlank(data.get("4"))) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]来源为空", row,data.get("0")), 400, null);
		}
		String sourceCode = getUserSourceCode(data.get("4"));
		if(StringUtils.isBlank(sourceCode)) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]来源code为空", row,data.get("0")), 400, null);
		}
		customer.setSourceCode(sourceCode);
		customer.setSourceValue(data.get("4"));

		if(!StringUtils.isBlank(data.get("5"))) {
			customer.setBirthday(data.get("5"));
		}

		if(StringUtils.isBlank(data.get("6"))) {
			throw new BusinessException(String.format("第[%s]条导入用户失败，登录名[%s]邮箱为空", row,data.get("0")), 400, null);
		}
		customer.setEmail(data.get("6"));

		if(!StringUtils.isBlank(data.get("7"))) {
			if(StringUtils.equals(data.get("7"), "女")) {
				customer.setSex("0");
			} else {
				customer.setSex("1");
			}
		}

		customer.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		customer.setState("1");
		customer.setCreateTime(new Date());
		return customer;
	}

	/**
	 * 验证用户是否存在
	 * @param loginName
	 * @return
	 */
	private boolean isUserExist(String loginName) {
		if(StringUtils.isBlank(loginName)) {
			return true;
		}
		Customer customer = new Customer();
		customer.setUsername(loginName);
		customer.setState("1");
		List<Map<String, Object>> users = this.customerMapper.selectCustomerEqual(customer);
		if (CollectionUtils.isEmpty(users)) {
			return false;
		}

		return true;
	}

	/**
	 * 初始化客户来源map
	 */
	private void initSourceMap() {
		DictModel dictModel = new DictModel();
		dictModel.setType("customerSource");
		sourceCodeMap = dictService.queryDict(dictModel);
	}

	private String getUserSourceCode(String name) {
		if(CollectionUtils.isEmpty(sourceCodeMap)) {
			initSourceMap();
		}

		if(CollectionUtils.isEmpty(sourceCodeMap)) {
			throw new BusinessException("导入失败，查询客户来源失败", 400, null);
		}


		for (Map<String, Object> dataMap : sourceCodeMap) {
			if(StringUtils.equals(dataMap.get("value").toString(), name)) {
				return dataMap.get("code").toString();
			}
		}

		return null;
	}

}
